package com.wangp.mywrite.s_netty.chat_group.protocol;

import com.wangp.mywrite.s_netty.chat_group.message.Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;

/**
 * @author tooStronger
 * @date 2023/4/18
 */
@Slf4j
public class MessageCodec extends ByteToMessageCodec<Message> {

    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
        // 魔数: 4字节
        out.writeBytes(new byte[]{1, 2, 3, 4});
        // 版本号: 1字节
        out.writeByte(1);
        // 序列化算法: 1字节 0-jdk序列化 1-json序列化
        out.writeByte(0);
        // 指令类型: 1字节
        out.writeByte(msg.getMessageType());
        // 请求序列: 4字节
        out.writeInt(msg.getSequenceId());
        // 填充
        out.writeByte(0xff);
        // 先获取内容的字节数组
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(msg);
        byte[] bytes = bos.toByteArray();
        // 正文长度
        out.writeInt(bytes.length);
        // 消息正文
        out.writeBytes(bytes);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int magicNum = in.readInt();
        byte version = in.readByte();
        byte serializerType = in.readByte();
        byte messageType = in.readByte();
        int sequenceId = in.readInt();
        in.readByte();
        int len = in.readInt();
        byte[] bytes = new byte[len];
        in.readBytes(bytes, 0, len);
        if (serializerType == 0) {
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            Message msg = (Message) ois.readObject();

            log.debug("{},{},{},{},{},{}", magicNum, version, serializerType, messageType, sequenceId, len);
            log.debug("msg = {}", msg);
            out.add(msg);
        }
    }
}
